package com.ruoyi.business.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.forms.fields.PdfFormField;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.annot.PdfWidgetAnnotation;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.properties.HorizontalAlignment;
import com.ruoyi.common.exception.base.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public final class PDF7Utils {

    public static final String IMAGE_PNG_BASE_64 = "data:image/png;base64,";

    /**
     * 填充pdf模板
     *
     * @param templateUrl   填充的模板地址
     * @param outputFileUrl 导出的模板地址
     * @param fieldMap      填充的字段map
     * @param imageMap      填充的图片
     * @return 填充的结果
     */
    public static void fillPdfTemplate(String templateUrl, String outputFileUrl, Map<String, String> fieldMap, Map<String, String> imageMap) {
        try (
                PdfDocument pdfDocument = new PdfDocument(new PdfReader(templateUrl), new PdfWriter(outputFileUrl))
        ) {
            // 2. 获取表单对象
            PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDocument, true);
            // 3. 填充文本（支持中文）
            PdfFont font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H");

            // 填充表单字段
            for (Map.Entry<String, String> entry : fieldMap.entrySet()) {
                if (entry.getValue() != null) {
                    PdfFormField nameField = form.getField(entry.getKey());
                    if (nameField != null) {
                        // 动态计算字号
                        float fontSize = 12; // 初始字号
                        if(!nameField.getWidgets().isEmpty()){
                            // 获取文本框物理尺寸
                            Rectangle rect = nameField.getWidgets().get(0).getRectangle().toRectangle();
                            float maxWidth = rect.getWidth() - 4; // 保留2pt边距
                            float textWidth = font.getWidth(entry.getValue(), fontSize);
                            while (textWidth > maxWidth && fontSize > 4) { // 最小字号4pt
                                fontSize -= 0.5f;
                                textWidth = font.getWidth(entry.getValue(), fontSize);
                            }
                        }
                        nameField.setFont(font);
                        nameField.setFontSize(fontSize);
                        nameField.setValue(entry.getValue());
                    }
                }
            }
            // 插入图片
            for (Map.Entry<String, String> entry : imageMap.entrySet()) {
                if (entry.getValue() != null) {
                    if (entry.getValue().startsWith(IMAGE_PNG_BASE_64)) {
                        byte[] imageBytes = java.util.Base64.getDecoder().decode(
                                entry.getValue().split(",")[1].getBytes()
                        );
                        PdfFormField imageField = form.getField(entry.getKey());
                        if (imageField == null) {
                            continue;
                        }
                        ImageData imageData = ImageDataFactory.create(imageBytes);
                        Image image = new Image(imageData);
//                        image.setHorizontalAlignment(HorizontalAlignment.CENTER);  // 设置水平居中:ml-citation{ref="5" data="citationList"}
                        List<PdfWidgetAnnotation> widgets = imageField.getWidgets();
                        for (PdfWidgetAnnotation widget : widgets) {
                            // 4. 获取域坐标与尺寸
                            Rectangle fieldRect = widget.getRectangle().toRectangle();
                            // 5. 图片自适应缩放
                            image.scaleToFit(fieldRect.getWidth()*1.4f, fieldRect.getHeight()*1.4f);
                            // 6. 绘制到域位置
                            PdfPage page = widget.getPage();
                            try(Canvas canvas = new Canvas(page, fieldRect)){
                                image.setFixedPosition(fieldRect.getLeft(), fieldRect.getBottom());
                                canvas.add(image);
                            }
                        }
                    }
                }
            }
            form.flattenFields();
        } catch (Exception e) {
            log.error("pdf模板填充失败！！！", e);
            throw new BaseException("pdf模板填充失败！！！");
        }
    }

    public static String generateQRCodeImage(String text, int width, int height) throws WriterException, IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 设置编码格式为UTF-8
        hints.put(EncodeHintType.MARGIN, 0);
        BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
        MatrixToImageWriter.writeToStream(bitMatrix, "PNG", baos); // 输出图片格式为PNG
        byte[] imageBytes = baos.toByteArray(); // 获取字节数据
        String base64Image = Base64.encodeBase64String(imageBytes); // 将字节数据编码为Base64字符串
        return IMAGE_PNG_BASE_64 + base64Image; // 创建img标签的src属性值
    }

    public static void main(String[] args) throws IOException, WriterException {
        String projectSignPath = System.getProperty("user.dir") + "/uploadPath/sign";
        String signTemplate = projectSignPath + "/template/行风自律承诺书-护士.pdf";
        String signFile = "D:\\工作空间\\123.png";
        String signOutTemplate = projectSignPath + "/files/华山医院进修生告知书-测试.pdf";
//        String signOutTemplate1 = projectSignPath+"/files/华山医院进修生告知书-测试1.pdf";
        String base64String = Base64.encodeBase64String(FileUtils.readFileToByteArray(new File(signFile)));
        base64String = IMAGE_PNG_BASE_64 + base64String;
        Map<String, String> txtMap = new HashMap<>();
        txtMap.put("deptName", "ETC/进修行风自律承诺书行风自律承诺书行风自律承诺书");
        txtMap.put("selfCurrentYear", "2025");
        txtMap.put("selfCurrentMonth", "03");
        txtMap.put("selfCurrentDate", "26");
        txtMap.put("otherCurrentYear", "2025");
        txtMap.put("otherCurrentMonth", "03");
        txtMap.put("otherCurrentDate", "26");
        txtMap.put("sureYear", "2025");
        txtMap.put("sureMonth", "03");
        txtMap.put("sureDate", "26");
        Map<String, String> imgMap = new HashMap<>();
        imgMap.put("selfSign", base64String);
        imgMap.put("otherSign", base64String);
        fillPdfTemplate(signTemplate, signOutTemplate, txtMap, imgMap);

//        System.out.println(generateQRCodeImage("测试",300,300));
    }


}

